﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;
using System.Xml.Serialization;

namespace QuiddichWPF.Config
{
    /// <summary>
    /// Utilitaire de sérialisation des préférences utilisateur
    /// </summary>
    [Serializable]
    public class Configuration
    {
        private static String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Quidditch";
        private static String fileName = @"config.xml";
        private static String pathFile = path + @"\" + fileName;

        XmlSerializer serializer = new XmlSerializer(typeof(List<WindowConfig>));

        private List<WindowConfig> listWindowsParams = new List<WindowConfig>();

        private Dictionary<String, WindowConfig> windowsParams = new Dictionary<string, WindowConfig>();

        /// <summary>
        /// Liste des préférences de l'utilisateur pour toutes les fenêtres de l'application
        /// </summary>
        public List<WindowConfig> WindowConfigs
        {
            get;
            set;
        }

        public WindowConfig this[String windowName]
        {
            get
            {
                WindowConfig winConf = null;
                windowsParams.TryGetValue(windowName,out winConf);
                return winConf;
            }
        }

        private static Configuration instance;

        /// <summary>
        /// L'utilitaire de sérialisation
        /// </summary>
        public static Configuration ConfigurationUtility
        {
            get
            {
                if (instance == null) instance = new Configuration();

                return instance;
            }
        }

        private Configuration() { }

        /// <summary>
        /// Ajout d'une préférence d'une fenêtre
        /// </summary>
        /// <param name="window"></param>
        public void RegisterWindowConfig(Window window)
        {
            double x;
            double y;
            double width;
            double height;

            if(window.WindowState != WindowState.Normal)
            {
                x = window.RestoreBounds.Left;
                y = window.RestoreBounds.Top;
                width = window.RestoreBounds.Width;
                height = window.RestoreBounds.Height;
            }
            else
            {
                x = window.Left;
                y = window.Top;
                width = window.Width;
                height = window.Height;
            }

            String windowName = window.ToString();
            WindowState state = window.WindowState;

            WindowConfig config;

            if(windowsParams.ContainsKey(windowName))
            {
                windowsParams.TryGetValue(windowName, out config);
                config.Update(windowName, x, y, width, height, state);
            }
            else
            {
                config = new WindowConfig(windowName, x, y, width, height, state);
                windowsParams.Add(windowName,config);
            }
        }

        /// <summary>
        /// Sauvegarde dans un fichier XML sur le disque dur
        /// </summary>
        public void Save()
        {
            listWindowsParams.AddRange(windowsParams.Values);

            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            StreamWriter stream = new StreamWriter(pathFile);
            
            serializer.Serialize(stream, listWindowsParams);

            stream.Close();
        }

        /// <summary>
        /// Chargement des préférences utilisateur
        /// </summary>
        public void Load()
        {
            if (File.Exists(pathFile))
            {
                StreamReader stream = new StreamReader(pathFile);
                
                try
                { 
                    listWindowsParams = serializer.Deserialize(stream) as List<WindowConfig>;

                    foreach (WindowConfig config in listWindowsParams)
                    {
                        windowsParams.Add(config.Name, config);
                    }

                    listWindowsParams.Clear();
                }
                catch(InvalidOperationException ex){ }

                stream.Close();
            }  
        }

        /// <summary>
        /// Configuration d'une fenêtre
        /// </summary>
        /// <param name="windowToConfig"> Fenêtre à configurer </param>
        internal bool Configure(Window windowToConfig)
        {
            WindowConfig config = this[windowToConfig.ToString()];

            if(config != null)
            {
                windowToConfig.WindowState = config.State;
                windowToConfig.Left = config.X;
                windowToConfig.Top = config.Y;
                windowToConfig.Width = config.Width;
                windowToConfig.Height = config.Height;

                return true;
            }
            else
            {
                if (windowToConfig.Equals(Application.Current.MainWindow))
                    windowToConfig.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                else
                    windowToConfig.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                return false;
            }
        }
    }
}
